package util;

import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import bean.*;
import proxy.IConnection;

/**
 * Handles the connection with Apache HttpClient.
 * 
 * @author tanjian
 * 
 */
public class ConnectionUtil implements IConnection {

	private static final String FORMAT_JSON = "JSON";
	private static final String FORMAT_DOM = "DOM";
	private static final String FORMAT_ITEM = "ITEM";

	private static final String ServerUrl = "http://219.143.122.5:8080";

	private static ConnectionUtil conn;

	private static HttpClient httpclient;

	/**
	 * Get only one connection instant.
	 * 
	 * @return
	 */
	public static ConnectionUtil getConn() {
		if (null == conn) {
			conn = new ConnectionUtil();
		}
		return conn;
	}

	/**
	 * Send the common interface to remote server and get the response.
	 */
	public String conn(CommonInterface ci) throws Exception {
		// TODO Auto-generated method stub
		String response = "";
		switch (ci.getEnumType()) {
		case GET:
			response = get(ci.getParams(), getUrl(ci));
			break;
		case DELETE:
			response = delete(ci.getParams());
			break;
		case POST:
			response = post(ci.getParams(), getUrl(ci));
			break;
		case PUT:
			response = put(ci.getParams());
			break;
		}
		return response;
	}

	/**
	 * Send the common interface to remote server and get the response.
	 */
	public Object conn(CommonInterface ci, String format) throws Exception {
		if (getFormatItem().equals(format)) {
			return DOMUtil.toItemList(JsonUtil.toDOM(conn(ci)));
		} else if (getFormatDom().equals(format)) {
			return JsonUtil.toDOM(conn(ci));
		} else if (getFormatJson().equals(format)) {
			return conn(ci);
		} else return null;
	}

	/**
	 * Delete method
	 */
	public String delete(ArrayList<Item> pt) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * Get method
	 */
	public String get(ArrayList<Item> pt, String url) throws Exception {
		// TODO Auto-generated method stub

		// Put params into HttpGet method
		HttpGet httpGet = new HttpGet(getParams(pt, url));

		// Get the result and transform from json to DOM then to items

		return getString(httpGet);
	}

	/**
	 * Post method
	 */
	public String post(ArrayList<Item> pt, String url) throws Exception {
		// TODO Auto-generated method stub
		HttpPost httpost = new HttpPost(url);
		//
		// httpost.getParams().setParameter("http.protocol.content-charset",
		// HTTP.UTF_8);
		// httpost.getParams().setParameter(HTTP.CONTENT_ENCODING, HTTP.UTF_8);
		// httpost.getParams().setParameter(HTTP.CHARSET_PARAM, HTTP.UTF_8);
		// httpost.getParams().setParameter(HTTP.DEFAULT_PROTOCOL_CHARSET,
		// HTTP.UTF_8);

		httpost.setEntity(new StringEntity(ItemUtil.toJson(pt)));

		// Set content type of request header
		httpost.setHeader("Content-Type", "text/xml;charset=UTF-8");

		// Get the result and transform from json to DOM then to items
		return getString(httpost);
	}

	/**
	 * Put method.
	 */
	public String put(ArrayList<Item> pt) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * Get only one hc instant.
	 * 
	 * @return
	 */
	public static HttpClient getHC() {
		if (null == httpclient) {
			httpclient = new DefaultHttpClient();

			// httpclient.getParams().setParameter(
			// "http.protocol.content-charset", HTTP.UTF_8);
			// httpclient.getParams().setParameter(HTTP.CONTENT_ENCODING,
			// HTTP.UTF_8);
			// httpclient.getParams().setParameter(HTTP.CHARSET_PARAM,
			// HTTP.UTF_8);
			// httpclient.getParams().setParameter(HTTP.DEFAULT_PROTOCOL_CHARSET,
			// HTTP.UTF_8);
		}
		return httpclient;
	}

	/**
	 * Handle the connection
	 * 
	 * @param request
	 * @return
	 */
	private String getString(HttpUriRequest request) {

		HttpResponse response;
		HttpEntity entity;
		String result = "";

		try {

			System.out.println("Request is: "
					+ request.getRequestLine().toString());
			System.out.println("Connecting to server...");
			response = getHC().execute(request);
			System.out.println("Get response from server...");
			entity = response.getEntity();
			System.out.println("Response Status is: "
					+ response.getStatusLine());
			result = EntityUtils.toString(entity);
			System.out.println("Response is: " + result);

			// XmlUtil.toXML(JsonUtil.toDOM(result), "Response.xml");

		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * Constructs a server url
	 * 
	 * @param ci
	 * @return
	 */
	public static String getUrl(CommonInterface ci) {
		return getServerurl() + ci.getPath() + ci.getSubPath();
	}

	public static String getServerurl() {
		return ServerUrl;
	}

	/**
	 * Constructs parameters in url
	 * 
	 * @param pt
	 * @param url
	 * @return
	 */
	public static String getParams(ArrayList<Item> pt, String url) {
		if (pt.isEmpty())
			return null;
		StringBuffer buf = new StringBuffer();
		buf.append("?");
		// url += "?";
		boolean hasFormerParam = false;
		for (Item item : pt) {
			if (null == item.getParentItem()) {
				continue;
			}
			if (null != item.getValue() && !item.getValue().equals("")) {
				if (hasFormerParam) {
					// url += "&";
					buf.append("&");
				}
				buf.append(item.getName() + "=" + item.getValue());
				// url += item.getName() + "=" + item.getValue();
				hasFormerParam = true;
			}
		}

		return url + buf.toString();
	}

	public static String getFormatJson() {
		return FORMAT_JSON;
	}

	public static String getFormatDom() {
		return FORMAT_DOM;
	}

	public static String getFormatItem() {
		return FORMAT_ITEM;
	}
}
